//promise并发执行
if (!Promise.allSettled) {
    Promise.allSettled = promises =>
        Promise.all(
            promises.map((promise, i) =>
                promise
                    .then(value => ({
                        status: "fulfilled",
                        value,
                    }))
                    .catch(reason => ({
                        status: "rejected",
                        reason,
                    }))
            )
        );
}

//https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled

module.exports = {
    parallel: async function (data, func, def = {}) {
        if (Array.isArray(data)) {
            let result = await Promise.allSettled(typeof (func) == 'function' ? data.map(func) : data);
            let t = [];
            for (let r of result) {
                if (r.status == 'fulfilled') {
                    t.push(r.value);
                } else {
                    t.push(def);
                }
            }
            return t;
        } else {
            let keys = Object.keys(data);
            let values = Object.values(data);
            let result = await Promise.allSettled(typeof (func) == 'function' ? values.map(func) : values);
            let t = {};
            for (let [i, r] of result.entries()) {
                if (r.status == 'fulfilled') {
                    t[keys[i]] = r.value;
                } else {
                    t[keys[i]] = def;
                }
            }
            return t;
        }
    },

    parallelSimple: async function (data, elements) {
        let arr = [];
        let keys = Object.keys(elements);
        let values = Object.values(elements);
        let entries = Object.entries(elements);
        //封装promise数组
        for (let d of data) {
            for (let e of entries) {
                let k = e[0];
                let fn = e[1][0];
                let v = e[1].slice(1);
                arr.push(fn(...v.map(vv => eval('(' + vv + ')'))));//d[vv]
            }
        }
        //执行
        let result = await Promise.allSettled(arr);
        let tmp = [];
        for (let r of result) {
            if (r.status == 'fulfilled') {
                tmp.push(r.value);
            } else {
                tmp.push('');
            }
        }
        //切割结果
        let r = [];
        for (let i = 0; i < tmp.length; i += keys.length) {
            r.push(tmp.slice(i, i + keys.length));
        }
        //合并数据
        for (let [i, d] of data.entries()) {
            for (let [index, key] of keys.entries()) {
                d[key] = r[i][index];
            }
        }
        return data;
    }
};